package com.iplant.ams.serviceImpl.dao.ams;

import com.iplant.ams.service.po.ams.AMSPurchaseRequest;
import com.iplant.base.po.OutResult;
import com.iplant.base.po.Pagination;
import com.iplant.base.po.ServiceResult;
import com.iplant.base.po.enums.ExceptionTypes;
import com.iplant.base.utils.general.CalendarTool;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.basic.service.po.bms.BMSEmployee;
import com.iplant.basic.serviceImpl.dao.TaskBaseDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

public class AMSPurchaseRequestDAO extends TaskBaseDao<AMSPurchaseRequest> {

    private static Logger logger = LoggerFactory.getLogger(AMSPurchaseRequestDAO.class);

    private static AMSPurchaseRequestDAO Instance = null;

    public static AMSPurchaseRequestDAO getInstance() {
        if (Instance == null) {
            Instance = new AMSPurchaseRequestDAO();
        }
        return Instance;
    }

    private AMSPurchaseRequestDAO() {
        super(AMSPurchaseRequest.class);
    }

    @Override
    protected void Initialize() {
        super.SetInstance(this);
    }

    /**
     * 添加或修改采购申请单
     *
     * @param wLoginUser
     * @param wItem
     * @param wErrorCode
     * @return
     */
    public int Update(BMSEmployee wLoginUser, AMSPurchaseRequest wItem,
                      OutResult<Integer> wErrorCode) {
        int wResult = 0;

        try {
            // 参数异常
            if (wItem == null) {
                wErrorCode.set(ExceptionTypes.Parameter.getValue());
                return wResult;
            }

            wItem.setUserInfo(wLoginUser);
            wResult = this.UpdatePo(wLoginUser, wItem, wErrorCode);

        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error(ex.toString());
        }

        return wResult;
    }

    /**
     * 单条删除采购申请单
     *
     * @param wLoginUser
     * @param wAMSPurchaseRequest
     * @param wErrorCode
     * @return
     */
    public ServiceResult<Integer> Delete(BMSEmployee wLoginUser, AMSPurchaseRequest wAMSPurchaseRequest,
                                         OutResult<Integer> wErrorCode) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);

        try {
            if (wAMSPurchaseRequest == null || wAMSPurchaseRequest.getID() <= 0) {
                wErrorCode.set(ExceptionTypes.Parameter.getValue());
                return wResult;
            }

            wResult.Result = super.DeletePO(wLoginUser, wAMSPurchaseRequest, wErrorCode);

//            String wSQL = StringUtils.Format(
//                    "DELETE FROM {0}.ams_purchase_request WHERE ID = {1}",
//                    super.getDBName(), wAMSPurchaseRequest.getID());
//
//            Map<String, Object> wParamMap = new HashMap<>();
//
//            wSQL = this.DMLChange(wSQL);
//            wResult.Result = super.Update(wSQL, wParamMap);
        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error(ex.toString());
        }

        return wResult;
    }

    /**
     * 批量刪除采购申请单
     *
     * @param wLoginUser
     * @param wIDList
     * @param wErrorCode
     */
    public ServiceResult<Integer> DeleteList(BMSEmployee wLoginUser, List<Integer> wIDList,
                                             OutResult<Integer> wErrorCode) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);

        try {
            if (wIDList == null || wIDList.isEmpty()) {
                wErrorCode.set(ExceptionTypes.Parameter.getValue());
                return wResult;
            }
            wIDList.removeIf(p -> p <= 0);
            if (wIDList.isEmpty()) {
                wErrorCode.set(ExceptionTypes.Parameter.getValue());
                return wResult;
            }

            // 批量删除SQL语句
            String wSQL = StringUtils.Format(
                    "DELETE FROM {0}.ams_purchase_request WHERE ID in ({1})",
                    super.getDBName(), StringUtils.Join(",", wIDList));
            Map<String, Object> wParamMap = new HashMap<>();
            wSQL = this.DMLChange(wSQL);
            wResult.Result = super.Update(wSQL, wParamMap);
        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error(ex.toString());
        }

        return wResult;
    }

    /**
     * 条件查询
     *
     * @param wLoginUser
     * @param wIDs
     * @param wName
     * @param wCode
     * @param wCreatorID
     * @param wActive
     * @param wStartTime
     * @param wEndTime
     * @param wPagination
     * @param wErrorCode
     * @return
     */
    public List<AMSPurchaseRequest> AMS_QueryPurchaseRequestList(
            BMSEmployee wLoginUser, List<Integer> wIDs, String wName, String wCode, int wCreatorID,
            int wActive, List<Integer> wStateIDList, String wReceiverName, String wReceiverPhone,
            Calendar wStartTime, Calendar wEndTime, Pagination wPagination,
            OutResult<Integer> wErrorCode) {
        List<AMSPurchaseRequest> wResultList = new ArrayList<>();

        try {
            // ID List
            if (wIDs == null) {
                wIDs = new ArrayList<>();
            }
            wIDs.removeIf(p -> p <= 0);

            // StateID List
            if (wStateIDList == null) {
                wStateIDList = new ArrayList<>();
            }

            // 时间的处理
            Calendar wBaseTime = CalendarTool.getBasicDate();
            wBaseTime.set(2000, 1, 1);
            if (wStartTime == null || wStartTime.compareTo(wBaseTime) < 0) {
                wStartTime = wBaseTime;
            }
            if (wEndTime == null || wEndTime.compareTo(wBaseTime) < 0) {
                wEndTime = wBaseTime;
            }
            if (wStartTime.compareTo(wEndTime) > 0) {
                return wResultList;
            }

            String wSQL = StringUtils.Format("SELECT t1.* FROM {0}.ams_purchase_request t1" +
                            " WHERE t1.ID > 0" +
                            " AND (:ID = '''' or t1.ID IN (''{1}'')) " +
                            " AND (:Name = '''' OR t1.Name like :Name) " +
                            " AND (:Code = '''' OR t1.Code like :Code) " +
                            " AND (:CreatorID <= 0 OR t1.CreatorID = :CreatorID ) " +
                            " AND (:Active < 0 OR t1.Active = :Active) " +
                            " AND (:StartTime <= str_to_date(''2010-01-01'', ''%Y-%m-%d'') OR :StartTime <= t1" +
                            ".CreateTime) " +
                            " AND (:EndTime <= str_to_date(''2010-01-01'', ''%Y-%m-%d'') OR :EndTime >= t1" +
                            ".CreateTime) " +
                            " AND (:Status = '''' OR t1.CurrentStatus IN (''{2}'')) " +
                            " AND (:ReceiverName = '''' OR t1.ReceiverName like :ReceiverName) " +
                            " AND (:ReceiverPhone = '''' OR t1.ReceiverPhone like :ReceiverPhone) "
                    , super.getDBName(), StringUtils.Join("','", wIDs), StringUtils.Join("','", wStateIDList));

            Map<String, Object> wParamMap = new HashMap<>();
            wParamMap.put("ID", StringUtils.Join(",", wIDs));
            wParamMap.put("Name", StringUtils.isEmpty(wName) ? "" : ("%" + wName + "%"));
            wParamMap.put("Code", StringUtils.isEmpty(wCode) ? "" : ("%" + wCode + "%"));
            wParamMap.put("CreatorID", wCreatorID);
            wParamMap.put("Active", wActive);
            wParamMap.put("Status", StringUtils.Join(",", wStateIDList));
            wParamMap.put("StartTime", wStartTime);
            wParamMap.put("EndTime", wEndTime);
            wParamMap.put("ReceiverName", StringUtils.isEmpty(wReceiverName) ? "" : ("%" + wReceiverName + "%"));
            wParamMap.put("ReceiverPhone", StringUtils.isEmpty(wReceiverPhone) ? "" : ("%" + wReceiverPhone + "%"));

            wSQL = this.DMLChange(wSQL);

            wResultList = this.QueryForList(wSQL, wParamMap, wPagination, AMSPurchaseRequest.class);
        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error(ex.toString());
        }

        return wResultList;
    }

    /**
     * 查单条
     *
     * @param wLoginUser
     * @param wID
     * @param wCode
     * @param wErrorCode
     * @return
     */
    public AMSPurchaseRequest AMS_QueryPurchaseRequest(BMSEmployee wLoginUser, int wID, String wCode,
                                                       OutResult<Integer> wErrorCode) {
        AMSPurchaseRequest wResult = new AMSPurchaseRequest();

        try {
            List<AMSPurchaseRequest> wList = null;
            if (wID > 0) {
                // ID查询
                wList = this.AMS_QueryPurchaseRequestList(wLoginUser, StringUtils.parseListArgs(wID),
                        "", "", -1, -1, null, "", "",
                        CalendarTool.getBasicDate(), CalendarTool.getBasicDate(), Pagination.getMaxSize(), wErrorCode);
            } else if (StringUtils.isNotEmpty(wCode)) {
                // Code查询
                wList = this.AMS_QueryPurchaseRequestList(wLoginUser, null,
                        "", wCode, -1, -1, null, "", "",
                        CalendarTool.getBasicDate(), CalendarTool.getBasicDate(), Pagination.getMaxSize(), wErrorCode);
            }
            if (wList == null || wList.size() != 1) {
                return wResult;
            }
            wResult = wList.get(0);
        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error("SelectByIDorCode", ex);
        }

        return wResult;
    }


    //region 父类方法

    /**
     * 获取发起的任务列表
     *
     * @param wLoginUser
     * @param wCreatorID
     * @param wEventIDs
     * @param wStartTime
     * @param wEndTime
     * @param wPagination
     * @param wErrorCode
     * @return
     */
    public List<AMSPurchaseRequest> BFC_GetLaunchTaskList(BMSEmployee wLoginUser,
                                                          int wCreatorID, List<Integer> wEventIDs,
                                                          Calendar wStartTime, Calendar wEndTime,
                                                          Pagination wPagination, OutResult<Integer> wErrorCode) {

        return this.AMS_QueryPurchaseRequestList(wLoginUser, null, "", "", wCreatorID, -1, null,
                "", "", wStartTime, wEndTime, wPagination, wErrorCode);
    }

    /**
     * 任务提交
     *
     * @param wLoginUser
     * @param wTList
     * @param wErrorCode
     */
    @Override
    public void BFC_UpdateTaskList(BMSEmployee wLoginUser, List<AMSPurchaseRequest> wTList,
                                   OutResult<Integer> wErrorCode) {
        for (AMSPurchaseRequest wItem : wTList) {
            this.Update(wLoginUser, wItem, wErrorCode);
        }
    }

    /**
     * 获取单条任务
     *
     * @param wLoginUser 用户
     * @param wID        任务ID
     * @param wCode      任务编号
     * @param wErrorCode 错误码
     * @return
     */
    @Override
    public AMSPurchaseRequest BFC_GetTaskInfo(BMSEmployee wLoginUser, int wID, String wCode,
                                              OutResult<Integer> wErrorCode) {
        return this.AMS_QueryPurchaseRequest(wLoginUser, wID, wCode, wErrorCode);
    }

    /**
     * 根据任务ID列表获取任务
     *
     * @param wLoginUser 用户
     * @param wTaskIDs   任务ID列表
     * @param wErrorCode 错误码
     * @return
     */
    public List<AMSPurchaseRequest> BFC_GetTaskList(BMSEmployee wLoginUser, List<Integer> wTaskIDs,
                                                    OutResult<Integer> wErrorCode) {
        return this.AMS_QueryPurchaseRequestList(wLoginUser, wTaskIDs, "", "", -1, -1,
                null, "", "", CalendarTool.getBasicDate(), CalendarTool.getBasicDate(),
                Pagination.getMaxSize(), wErrorCode);
    }
    //endregion
}
